﻿using System;
using System.Collections;
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using VisualWip.Core;
using VisualWip.Core.Interfaces;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;

namespace VisualWip.TFS2010Common
{
    public class TfsConnection : IPersistable
    {
        private const string TFSProjectNameKey = "project";
        private const string TFSMeKey = "me";
        private string _connectedAs;
        private int _retryCounter;
        private Project _teamProject;
        private TfsTeamProjectCollection _teamProjectCollection;
        private WorkItemStore _workItemStore;

        public TfsConnection()
        {
            _connectedAs = string.Empty;
            QueryContext = new Hashtable();
        }

        public string ProjectName { get; set; }
        public Uri ProjectCollectionUri { get; set; }

        public TfsTeamProjectCollection TeamProjectCollection
        {
            get { return _teamProjectCollection; }
        }

        public Project TeamProject
        {
            get
            {
                if (!IsConnected)
                    Connect();

                return _teamProject;
            }
        }


        public WorkItemStore WorkItemStore
        {
            get
            {
                if (!IsConnected)
                    Connect();

                return _workItemStore;
            }
        }

        public Hashtable QueryContext { get; protected set; }

        public bool IsConnected { get; private set; }

        #region IPersistable Members

        public PersistenceTree Persist(string name)
        {
            var settings = new PersistenceTree(name, this);
            settings.Add(() => ProjectCollectionUri);
            settings.Add(() => ProjectName);
            return settings;
        }

        public void Load(PersistenceTree settings)
        {
            ProjectCollectionUri = settings.Get(() => ProjectCollectionUri, null);
            ProjectName = settings.Get(() => ProjectName, string.Empty);
        }

        #endregion

        public void Connect()
        {
            Connect(String.Empty);
        }
        public void Connect(string dialogText)
        {
            if (NeedToPickProject())
                PickProject(dialogText);

            try
            {
                ConnectToTFS();
            }
            catch (Exception)
            {
                PickProject(dialogText);
                try
                {
                    ConnectToTFS();
                }
                catch (Exception)
                {
                    MessageBox.Show("Could not connect to Team Foundation Server. Application will now shutdown.");
                    Application.Current.Shutdown();
                    return;
                }
            }


            if (QueryContext.ContainsKey(TFSProjectNameKey))
                QueryContext.Remove(TFSProjectNameKey);
            QueryContext.Add(TFSProjectNameKey, _teamProject.Name);

            if (QueryContext.ContainsKey(TFSMeKey))
                QueryContext.Remove(TFSMeKey);
            QueryContext.Add(TFSMeKey, _connectedAs);
        }

        private bool NeedToPickProject()
        {
            return string.IsNullOrWhiteSpace(ProjectName) || ProjectCollectionUri == null ||
                   !ProjectCollectionUri.IsAbsoluteUri;
        }

        private void ConnectToTFS()
        {
            _teamProjectCollection =
                TfsTeamProjectCollectionFactory.GetTeamProjectCollection(ProjectCollectionUri);
            _teamProjectCollection.EnsureAuthenticated();

            _connectedAs = _teamProjectCollection.AuthorizedIdentity.DisplayName;
            _workItemStore = _teamProjectCollection.GetService<WorkItemStore>();
            _teamProject = _workItemStore.Projects[ProjectName];
            IsConnected = true;
        }

        private void PickProject(string dialogText)
        {
            using (
                var projectPicker = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false,
                                                          new UICredentialsProvider()))
            {
                if(!string.IsNullOrWhiteSpace(dialogText))
                    projectPicker.Text = dialogText;
                
                DialogResult dialogResult = projectPicker.ShowDialog();

                if (dialogResult == DialogResult.OK)
                {
                    _retryCounter = 0;
                    ProjectCollectionUri = projectPicker.SelectedTeamProjectCollection.Uri;
                    ProjectName = projectPicker.SelectedProjects[0].Name;
                }
                else
                {
                    _retryCounter += 1;
                    if (_retryCounter < 3)
                        PickProject(dialogText);
                }
            }
        }
    }
}